﻿// Standart kütüphaneler
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <fstream>
#include <stdio.h>
#include <time.h>
// Geliştirilen kütüphane ve sınıflar
#include "XmlMap.h"
#include "Cell.h"
#include "Wall.h"
#include "Object3d.h"
#include "CollDetection.h"
// Kullanılan ek kütüphaneler
#include "object.h"
#include "load_bmp.h"
#include "load_3ds.h"
#include "tinyxml.h"
#include "tinystr.h"
#include "imageloader.h"
#include <GL/glut.h>
#include <GL/glui.h>
#include <windows.h>
#include <mmsystem.h>
#include "text3d.h"

using namespace std;

enum State {START, INSTRUCTIONS, PLAY, MAP, PAUSE, END};
extern const float STEP_SIZE=1.0f;
extern Cell _oda;
extern Wall collidedWall;
static GLuint textureId[6];
vector<obj_type> objects;

vector<vector<float>> xmlMap;
vector<vector<float>> cellVector;
vector<vector<std::string>> objectVector;
vector<vector<std::string>> questionVector;

struct Character _karakter;
State game_state = START;

int visibility=0;
int dog;
int toy;
int chicken;
int chair;
int horse;

clock_t start;
double x=20;
double diff;
int soru=0;
int soruaktif=0;
string CevaplarText = "*";
GLUI *glui;
GLUI_EditText *edittext;
int main_window;
int toplama=0;
vector<int> randQuestions;
vector<int> randObjects;

int end_time;
string message;

string convertInt(int number)
{
	if (number == 0)
		return "0";
	string temp="";
	string returnvalue="";
	while (number>0)
	{
		temp+=number%10+48;
		number/=10;
	}
	for (unsigned int i=0;i<temp.length();i++)
		returnvalue+=temp[temp.length()-i-1];
	return returnvalue;
}

vector<int> randomArray(int size){
	//int array[20]; // create an empty array with 1024 fields
	vector<int> randArray;
	for (int i=0;i<size;i++) // loop through the array
	{

		randArray.push_back(rand() % size); // seed each element of the array with a random number
		if (i != 0) // If we are not looking at the 1st cell of the array (array[0]) then continue otherwise skip all the rest of the code
		{
			int k = i; // store the array cout in a temp variable
			for (int j=0;j<k;j++) // create a second loop, with a loop count == to the size of the array at its current state.
			{
				if (randArray[i]==randArray[j]) // compare the variable just created using the random value, to the rest of the array to see if it matches.
				{
					randArray.pop_back(); // if the value matches, then roll back the i variable by one so the entire add random thing is repeated over writing teh duplicate value
					k = k-1;
					i=i-1;
				}
			}
		}

	}


	return randArray;
}

GLuint loadTexture(Image *image) {
	GLuint textureId;
	glGenTextures(1, &textureId);
	glBindTexture(GL_TEXTURE_2D, textureId);
	gluBuild2DMipmaps(GL_TEXTURE_2D,
		GL_RGB,
		image->width, image->height,
		GL_RGB,
		GL_UNSIGNED_BYTE,
		image->pixels);
	return textureId;
}


void initRendering() {
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_COLOR_MATERIAL);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_NORMALIZE);
	glShadeModel(GL_SMOOTH);
	t3dInit();

	Image* image = loadBMP("giris.bmp");
	textureId[0] = loadTexture(image);
	delete image;
	image = loadBMP("redbrick.bmp");
	textureId[1] = loadTexture(image);
	delete image;
	image = loadBMP("Wood.bmp");
	textureId[2] = loadTexture(image);
	delete image;
	image = loadBMP("bitis.bmp");
	textureId[3] = loadTexture(image);
	delete image;
	image = loadBMP("dur.bmp");
	textureId[4] = loadTexture(image);
	delete image;
	image = loadBMP("inst.bmp");
	textureId[5] = loadTexture(image);
	delete image;
}

void initGame(){
	_karakter.theta=0;
	_karakter.xStart=0;
	_karakter.movingPoint=GL_FALSE;
	_karakter.posX=2;
	_karakter.posY=2;
	_karakter.posZ=0;
	_karakter.angle = 0.0f;

	string mapXml_s;
	char temp[256];
	ifstream mapfile;
	mapfile.open("map.xml",ifstream::in);
	while(!mapfile.eof())
	{				
		mapfile.getline(temp,256);
		mapXml_s.append(temp);
	}
	const char* mapXml;
	mapXml = mapXml_s.data();
	//Daha sonra bir tane XmlMap yaratıp bunu içine yüklüyorum.
	Map map(mapXml);
	//Xml yüklendikten sonra RealizeMap fonksiyonunu çagirmamız lazým çizimler için
	map.RealizeMap();

	cellVector = map.getCellVector();
	objectVector = map.getObjectVector();
	questionVector = map.getQuestionVector();

	randQuestions=randomArray(questionVector.size());
	randObjects= randomArray(objectVector.size());

	for(unsigned int i=0; i<objectVector.size(); i++)
	{
		ObjLoad(const_cast<char*>(objectVector[i][0].c_str()),const_cast<char*>(objectVector[i][1].c_str()));
		objects.push_back(object);
	}
	ObjLoad("solidx.3ds","horse.bmp" );
	objects.push_back(object);

	glClearColor(0.7f, 0.9f, 1.0f, 1.0f);
}

void control_cb( int control )
{  
	if(soruaktif==1){
		if(questionVector[randQuestions[soru]][1]==CevaplarText){
			game_state=MAP;
			cout<<"Dogru cevap"<<endl;
		}
		else message = "Yanlis cevap!";
	}

}

GLvoid mouse(int button, int state, int x, int y)
{
	if (button==GLUT_LEFT_BUTTON && state==GLUT_DOWN) 
	{
		_karakter.movingPoint=GL_TRUE;
		_karakter.xStart=x;
	}
	else
		_karakter.movingPoint=GL_FALSE;	

}

GLvoid motion(int x, int y) 
{
	if(_karakter.movingPoint)
	{
		_karakter.theta += .5*(x-_karakter.xStart);
		_karakter.xStart=x;
	}
	else
		_karakter.movingPoint=GL_FALSE;
	glutPostRedisplay();
}

void handleKeypress(unsigned char key, int x, int y) {
	if(game_state == START)
	{
		switch (key) {
		case 27: // "esc" key	
			exit(0);
			break;
		default:
			game_state = INSTRUCTIONS;
			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
			glutPostRedisplay();
			break;
		}
	}
	else if(game_state == INSTRUCTIONS)
	{
		switch (key) {
		case 27: // "esc" key
			game_state = START;
			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
			glutPostRedisplay();
		default:
			game_state = PLAY;
			start=clock();
			initGame();
			glClearColor(0.7f, 0.9f, 1.0f, 1.0f);
			glutPostRedisplay();
			break;
		}
	}
	else if(game_state == PLAY)
	{
		float deltaX,deltaY;
		switch (key) {
		case 27: // "esc" key
			game_state = PAUSE;
			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
			glutPostRedisplay();
			break;
		case 'B':
		case 'b':
			game_state = END;
			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
			end_time = (int)( clock() - start ) / (double) CLOCKS_PER_SEC;
			glutPostRedisplay();
			break;
		case 'V':
		case 'v':
			game_state = MAP;
			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
			glutPostRedisplay();
			break;
		case 'D':
		case 'd':
			deltaX = + STEP_SIZE * sin(3.14+(_karakter.theta*2*3.14)/360);
			deltaY = - STEP_SIZE * cos((_karakter.theta*2*3.14)/360);
			if(!areThereCollisions(&_karakter,_oda.walls,deltaX,deltaY))
			{
				_karakter.posX += deltaX;
				_karakter.posY += deltaY;

			}	
			else
			{
				if(collidedWall.angle != 0 && !areThereCollisions(&_karakter,_oda.walls,0,deltaY))
					_karakter.posY += deltaY;
				else if(!areThereCollisions(&_karakter,_oda.walls,deltaX,0)) 
					_karakter.posX += deltaX;
			}
			glutPostRedisplay();
			break;
		case 'A':
		case 'a':
			deltaX = - STEP_SIZE * sin(3.14+(_karakter.theta*2*3.14)/360);
			deltaY = + STEP_SIZE * cos((_karakter.theta*2*3.14)/360);
			if(!areThereCollisions(&_karakter,_oda.walls,deltaX,deltaY))
			{
				_karakter.posX += deltaX;
				_karakter.posY += deltaY;
			}	
			else
			{
				if(collidedWall.angle != 0 && !areThereCollisions(&_karakter,_oda.walls,0,deltaY))
					_karakter.posY += deltaY;
				else if(!areThereCollisions(&_karakter,_oda.walls,deltaX,0)) 
					_karakter.posX += deltaX;
			}
			glutPostRedisplay();
			break;
		case 'W':
		case 'w':
			deltaX = + STEP_SIZE * cos((_karakter.theta*2*3.14)/360);
			deltaY = - STEP_SIZE * sin((_karakter.theta*2*3.14)/360);
			if(!areThereCollisions(&_karakter,_oda.walls,deltaX,deltaY))
			{
				_karakter.posX += deltaX;
				_karakter.posY += deltaY;
			}
			else
			{
				if(collidedWall.angle != 0 && !areThereCollisions(&_karakter,_oda.walls,0,deltaY))
					_karakter.posY += deltaY;
				else if(!areThereCollisions(&_karakter,_oda.walls,deltaX,0)) 
					_karakter.posX += deltaX;
			}
			glutPostRedisplay();
			break;
		case 'S':
		case 's':
			deltaX = - STEP_SIZE * cos((_karakter.theta*2*3.14)/360);
			deltaY = + STEP_SIZE * sin((_karakter.theta*2*3.14)/360);
			if(!areThereCollisions(&_karakter,_oda.walls,deltaX,deltaY))
			{
				_karakter.posX += deltaX;
				_karakter.posY += deltaY;
			}	
			else
			{
				if(collidedWall.angle != 0 && !areThereCollisions(&_karakter,_oda.walls,0,deltaY))
					_karakter.posY += deltaY;
				else if(!areThereCollisions(&_karakter,_oda.walls,deltaX,0)) 
					_karakter.posX += deltaX;
			}
			glutPostRedisplay();
			break;
		case 'N':
		case 'n':
			_karakter.angle += 5; 
			glutPostRedisplay();
			break;
		case 'M':
		case 'm':
			_karakter.angle += -5;
			glutPostRedisplay();
			break;
		case 'E':
		case 'e':
			if(visibility==randObjects[0]){
				if(pow(_karakter.posX-4,2)+pow(_karakter.posY-4,2)<=7.89){
					visibility++;
					toplama++;
				}
				cout<<pow(_karakter.posX-4,2)+pow(_karakter.posY-4,2)<<endl;
				cout<<chicken<<endl;
				break;
			}
			if(visibility==randObjects[1]){
				if(pow(_karakter.posX-68,2)+pow(_karakter.posY-116,2)<=15.5){
					visibility++;
					toplama++;
				}
				cout<<pow(_karakter.posX-68,2)+pow(_karakter.posY-116,2)<<endl;
				cout<<toy<<endl;
				break;
			}
			if(visibility==randObjects[2]){
				if(pow(_karakter.posX-60,2)+pow(_karakter.posY-100,2)<=14.0){
					visibility++;
					toplama++;
				}
				cout<<pow(_karakter.posX-60,2)+pow(_karakter.posY-100,2)<<endl;
				cout<<horse<<endl;
				break;
			} 
			if(visibility==randObjects[3]){
				if(pow(_karakter.posX-68,2)+pow(_karakter.posY-4,2)<=16.0){
					visibility++;
					toplama++;
				}
				cout<<pow(_karakter.posX-68,2)+pow(_karakter.posY-4,2)<<endl;
				cout<<dog<<endl;
				break;
			} 
			if(visibility==randObjects[4]){
				if(pow(_karakter.posX-52,2)+pow(_karakter.posY-52,2)<=15.0){
					visibility++;
					toplama++;
				}
				break;
			}
			if(visibility==randObjects[5]){
				if(pow(_karakter.posX-67,6)+pow(_karakter.posY-27,6)<=15.0){
					visibility++;
					toplama++;
				}
				break;
			}
		}
	}
	else if(game_state == MAP)
	{
		switch (key) {
		case 27: // "esc" key
			game_state = PLAY;
			glClearColor(0.7f, 0.9f, 1.0f, 1.0f);
			glutPostRedisplay();
			break;
		}
	}
	else if(game_state == PAUSE)
	{
		switch (key) {
		case 27: // "esc" key
			game_state = START;
			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
			glutPostRedisplay();
			break;
		default:
			game_state = PLAY;
			glClearColor(0.7f, 0.9f, 1.0f, 1.0f);
			glutPostRedisplay();
			break;
		}
	}
	else if(game_state == END)
	{
		switch (key) {
		case 27: // "esc" key
			exit(0);
		default:
			game_state = START;
			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
			glutPostRedisplay();
			break;
		}
	}
}

void handleResize(int w, int h) {
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}

void drawScene() {
	if(game_state == START)
	{
		glPushMatrix();
		glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
		glLoadIdentity(); //Reset the drawing perspective

		GLfloat ambientColor[] = {0.4f, 0.4f, 0.4f, 1.0f};
		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

		GLfloat lightColor0[] = {0.6f, 0.6f, 0.6f, 1.0f};
		GLfloat lightPos0[] = {-0.5f, 0.5f, 1.0f, 0.0f};
		glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
		glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);

		//Draw the strings along the sides of a square
		if(textureId[0]!=-1)
		{
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, textureId[0]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,
				GL_TEXTURE_MIN_FILTER,
				GL_LINEAR_MIPMAP_LINEAR);
		}
		glBegin(GL_QUADS);
		glNormal3f(0.0, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 0.0f);	
		glVertex3f(-UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(1.0f, 0.0f);
		glVertex3f(UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(1.0f, 1.0f);
		glVertex3f(UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(0.0f, 1.0f);
		glVertex3f(-UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
		glEnd();

		if(textureId[0]!=-1)
		{
			glDisable(GL_TEXTURE_2D);
		}

		char* STRS[7] = {" ",
			" ",
			"Egitici labirente hosgeldin! ",
			" ", 
			"Oyuna baslamak herhangi bir tusa bas. ",
			" ",
			"Oyundan cikmak icin ise ESC tusuna basabilirsin."};

		glTranslatef(0.0f,-1 / 2 *0.2f,-4.0f);
		glScalef(0.15, 0.15, 0.15);
		glColor3f(1.0f, 0.0f, 0.0f);
		for(int i = 0; i < 7; i++) {
			glPushMatrix();
			glTranslatef(0, -i, 0);
			t3dDraw3D(STRS[i], 0, 0, 0.3f);
			glPopMatrix();
		}
		glColor3f(1.0f, 1.0f, 1.0f);
		glPopMatrix();
	}
	else if(game_state == INSTRUCTIONS)
	{
		glPushMatrix();
		glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
		glLoadIdentity(); //Reset the drawing perspective

		//Draw the strings along the sides of a square
		if(textureId[5]!=-1)
		{
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, textureId[5]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,
				GL_TEXTURE_MIN_FILTER,
				GL_LINEAR_MIPMAP_LINEAR);
		}
		glBegin(GL_QUADS);
		glNormal3f(0.0, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 0.0f);	
		glVertex3f(-UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(1.0f, 0.0f);
		glVertex3f(UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(1.0f, 1.0f);
		glVertex3f(UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(0.0f, 1.0f);
		glVertex3f(-UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
		glEnd();

		if(textureId[5]!=-1)
		{
			glDisable(GL_TEXTURE_2D);
		}

		char* STRS[8] = {"TALIMATLAR:",
			"W, A, S, D: 4 yonde hareket ", 
			"Fare: Saga veya sola bakma ",
			"E: Objeyi alma ",
			"M ve N: Yukari ve Asagi bakma ",
			"Esc: Oyunu durdurma ",
			" ",
			"Oyuna baslamak icin herhangi bir tusa basabilirsin!"};

		glTranslatef(0.0f,3 / 2 *0.2f,-4.0f);
		glScalef(0.15, 0.15, 0.15);
		glColor3f(0.0f, 0.0f, 0.0f);
		for(int i = 0; i < 8; i++) {
			glPushMatrix();
			glTranslatef(0, -i*1.5f, 0);
			t3dDraw3D(STRS[i], 0, 0, 0.3f);
			glPopMatrix();
		}
		glColor3f(1.0f, 1.0f, 1.0f);
		glPopMatrix();
	}
	else if(game_state == PLAY)
	{
		if(toplama==6)
		{
			game_state=END;
			end_time = (int)( clock() - start ) / (double) CLOCKS_PER_SEC;
		}
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glClearColor(0.7f, 0.9f, 1.0f, 1.0f);
		glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
		glLoadIdentity(); //Reset the drawing perspective

		glTranslatef(0.0f, 0.0f, -1.0f); //Move forward 15 units
		GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f};
		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
		diff=( clock() - start ) / (double) CLOCKS_PER_SEC;
		cout << diff << endl;
		if(diff>x)
		{
			soruaktif = 1;
			if(diff > x+10)
			{
				x = x+30;
				if(soru!=questionVector.size()-1)
					soru++;
				else
				{
					soru=0;
				}
				soruaktif = 0;
				game_state=PLAY;
				glutPostRedisplay();
			}
			glPushMatrix();
			glTranslatef(0.0f,1 / 2 *0.2f,-0.5f);
			glScalef(0.05, 0.05, 0.05);		
			glDisable(GL_TEXTURE_2D);
			glColor3f(1.0f, 1.0f, 1.0f);
			if(soruaktif==1)
				t3dDraw3D(questionVector[randQuestions[soru]][0], 0, 0, 0.3f);		
			glEnable(GL_TEXTURE_2D);
			glColor3f(1.0f, 1.0f, 1.0f);
			glPopMatrix();

			glPushMatrix();
			glTranslatef(0.0f,4.5f / 2 *0.2f,-0.5f);
			glScalef(0.05, 0.05, 0.05);		
			glDisable(GL_TEXTURE_2D);
			glColor3f(1.0f, 1.0f, 0.0f);
			t3dDraw3D(message.data(), 0, 0, 0.3f);		
			glEnable(GL_TEXTURE_2D);
			glColor3f(1.0f, 1.0f, 1.0f);
			glPopMatrix();
		}
		else if(message.size()<0)
			message.clear();
		glPushMatrix();
		glTranslatef(0.0f,5.5f / 2 *0.2f,-0.5f);
		glScalef(0.05, 0.05, 0.05);		
		glDisable(GL_TEXTURE_2D);
		glColor3f(1.0f, 1.0f, 0.0f);
		string time = "Suren: " + convertInt((int)diff) + " sn";
		t3dDraw3D(time.data(), 0, 0, 0.3f);		
		glEnable(GL_TEXTURE_2D);
		glColor3f(1.0f, 1.0f, 1.0f);
		glPopMatrix();

		glRotatef(_karakter.angle, 1.0f, 0.0f, 0.0f);

		GLfloat lightColor[] = {0.7f, 0.7f, 0.7f, 1.0f};
		GLfloat lightPos[] = {0.0f, 0.0f, 10.0f, 1.0f};
		glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
		glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

		glRotatef(90,0.0f,0.0f,1.0f);
		glRotatef(90,0.0f,1.0f,0.0f);
		glRotatef(_karakter.theta,0,0,1);

		glTranslatef(-_karakter.posX,-_karakter.posY,-_karakter.posZ);		
		_oda = Cell(vector<Wall>(),Wall(36,60,-1.9,72,120,0.2,1,1,1,0,textureId[2]),0,0,0,1,0x0f);
		for(unsigned int i=0; i < cellVector.size(); i++)
		{
			_oda.AddWall(Wall(cellVector[i][0],cellVector[i][1],cellVector[i][2],cellVector[i][3],cellVector[i][4],cellVector[i][5],cellVector[i][6],cellVector[i][7],cellVector[i][8],cellVector[i][9],textureId[1]));
		}
		_oda.Draw();

		Object3d obje;
		for(unsigned int i=0; i<objectVector.size(); i++)
		{
			obje = Object3d(atof(objectVector[i][2].c_str()),atof(objectVector[i][3].c_str()),atof(objectVector[i][4].c_str()),atof(objectVector[i][5].c_str()),atof(objectVector[i][6].c_str()),atof(objectVector[i][7].c_str()));
			if(visibility==randObjects[0] && i==0){
				object=objects[i];
				obje.Draw();
			}
			if(visibility==randObjects[1] && i==1){
				object=objects[i];
				obje.Draw();
			}
			if(visibility==randObjects[2] && i==2){
				object=objects[i];
				obje.Draw();
			}
			if(visibility==randObjects[3] && i==3){
				object=objects[i];
				obje.Draw();
			}
			if(visibility==randObjects[4] && i==4){
				object=objects[i];
				obje.Draw();
			}
			if(visibility==randObjects[5] && i==5){
				object=objects[i];
				obje.Draw();
			}
		}
	}
	else if(game_state == MAP)
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glClearColor(0.7f, 0.9f, 1.0f, 1.0f);
		glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
		glLoadIdentity(); //Reset the drawing perspective
		diff=( clock() - start ) / (double) CLOCKS_PER_SEC;
		cout << diff << endl;
		if(diff > x+10)
		{
			game_state=PLAY;		
		}
		glTranslatef(0.0f, 0.0f, -3.0f); //Move forward 15 units
		GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f};
		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

		glRotatef(90, 1.0f, 0.0f, 0.0f); //Rotate about the x-axis

		GLfloat lightColor[] = {0.7f, 0.7f, 0.7f, 1.0f};
		GLfloat lightPos[] = {0.0f, 0.0f, 10.0f, 1.0f};
		glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
		glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

		glRotatef(90,0.0f,0.0f,1.0f);
		glRotatef(90,0.0f,1.0f,0.0f);		

		glTranslatef(-36,-60, -100);	
		_oda = Cell(vector<Wall>(),Wall(36,60,-1.9,72,120,0.2,1,1,1,0,0),0,0,0,1,0x0f);//Wall(36,60,-1.9,72,120,0.2,1,1,1,0,textureId[1]),0,0,0,1,0x0f);
		for(unsigned int i=0; i < cellVector.size(); i++)
		{
			_oda.AddWall(Wall(cellVector[i][0],cellVector[i][1],0,cellVector[i][3],cellVector[i][4],0,cellVector[i][6],cellVector[i][7],cellVector[i][8],cellVector[i][9],textureId[1]));
		}
		_oda.Draw();

		Object3d obje;
		for(unsigned int i=0; i<objectVector.size(); i++)
		{
			obje = Object3d(atof(objectVector[i][2].c_str()),atof(objectVector[i][3].c_str()),atof(objectVector[i][4].c_str()),atof(objectVector[i][5].c_str()),atof(objectVector[i][6].c_str()),atof(objectVector[i][7].c_str()));
			if(visibility==randObjects[0] && i==0){
				object=objects[i];
				obje.Draw();
			}
			if(visibility==randObjects[1] && i==1){
				object=objects[i];
				obje.Draw();
			}
			if(visibility==randObjects[2] && i==2){
				object=objects[i];
				obje.Draw();
			}
			if(visibility==randObjects[3] && i==3){
				object=objects[i];
				obje.Draw();
			}
			if(visibility==randObjects[4] && i==4){
				object=objects[i];
				obje.Draw();
			}
			if(visibility==randObjects[5] && i==5){
				object=objects[i];
				obje.Draw();
			}
		}
		obje = Object3d(_karakter.posX,_karakter.posY,0,2,2,2);
		object=objects.back();
		obje.Draw();
	}
	else if(game_state == PAUSE)
	{
		glPushMatrix();
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
		glLoadIdentity(); //Reset the drawing perspective

		GLfloat ambientColor[] = {0.4f, 0.4f, 0.4f, 1.0f};
		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

		GLfloat lightColor0[] = {0.6f, 0.6f, 0.6f, 1.0f};
		GLfloat lightPos0[] = {-0.5f, 0.5f, 1.0f, 0.0f};
		glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
		glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);

		if(textureId[4]!=-1)
		{
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, textureId[4]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,
				GL_TEXTURE_MIN_FILTER,
				GL_LINEAR_MIPMAP_LINEAR);
		}
		glBegin(GL_QUADS);
		glNormal3f(0.0, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 0.0f);	
		glVertex3f(-UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(1.0f, 0.0f);
		glVertex3f(UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(1.0f, 1.0f);
		glVertex3f(UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(0.0f, 1.0f);
		glVertex3f(-UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
		glEnd();

		if(textureId[4]!=-1)
		{
			glDisable(GL_TEXTURE_2D);
		}

		const char* STRS[8] = {" ",
			" ",
			"Oyunu durdurdun! ",
			" ", 
			"Oyuna devam etmek icin herhangi bir tusa bas. ",
			" ",
			"Baslangic ekranina donmek icin ise", 
			"ESC tusuna basabilirsin."};
		glTranslatef(0.0f,4 / 2 *0.2f,-4.0f);
		glScalef(0.15, 0.15, 0.15);
		glColor3f(1.0f, 0.0f, 0.0f);
		for(int i = 0; i < 8; i++) {
			glPushMatrix();
			glTranslatef(0, -i, 0);
			t3dDraw3D(STRS[i], 0, 0, 0.3f);
			glPopMatrix();
		}
		glColor3f(1.0f, 1.0f, 1.0f);
		glPopMatrix();
	}
	else if(game_state == END)
	{
		glPushMatrix();
		glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
		glLoadIdentity(); //Reset the drawing perspective

		GLfloat ambientColor[] = {0.4f, 0.4f, 0.4f, 1.0f};
		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

		GLfloat lightColor0[] = {0.6f, 0.6f, 0.6f, 1.0f};
		GLfloat lightPos0[] = {-0.5f, 0.5f, 1.0f, 0.0f};
		glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
		glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);


		//Draw the strings along the sides of a square
		if(textureId[3]!=-1)
		{
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, textureId[3]);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,
				GL_TEXTURE_MIN_FILTER,
				GL_LINEAR_MIPMAP_LINEAR);
		}
		glBegin(GL_QUADS);
		glNormal3f(0.0, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 0.0f);	
		glVertex3f(-UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(1.0f, 0.0f);
		glVertex3f(UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(1.0f, 1.0f);
		glVertex3f(UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
		glTexCoord2f(0.0f, 1.0f);
		glVertex3f(-UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
		glEnd();

		if(textureId[3]!=-1)
		{
			glDisable(GL_TEXTURE_2D);
		}
		string score = "Suren: " + convertInt(end_time) + " saniye" ;
		const char* STRS[9] = {" ",
			" ",
			" ",
			" ", 
			"Tebrikler! Oyunu basariyla tamamladin.",
			score.data(),
			" ",
			"Baslangic ekranina donmek herhangi bir tusa bas. ",
			"Oyundan cikmak icin ise ESC tusuna basabilirsin."};
		glTranslatef(0.0f,-5 / 2 *0.2f,-4.0f);
		glScalef(0.10, 0.10, 0.10);
		glColor3f(1.0f, 1.0f,1.0f);
		for(int i = 0; i < 9; i++) {
			glPushMatrix();
			glTranslatef(0, -i*1.2, 0);
			t3dDraw3D(STRS[i], 0, 0, 0.3f);
			glPopMatrix();
		}
		glColor3f(1.0f, 1.0f, 1.0f);
		glPopMatrix();
	}
	glutSwapBuffers();
}

void myGlutIdle( void )
{
	/* According to the GLUT specification, the current window is 
	undefined during an idle callback.  So we need to explicitly change
	it if necessary */
	glutSetWindow(main_window);  

	glutPostRedisplay();
}

int main(int argc, char** argv) {
	//Initialize GLUT
	srand(time(NULL));

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);	
	glutInitWindowSize(1280, 720);
	//Create the window
	main_window = glutCreateWindow("Eğitici Labirent v1.0");
	initRendering();
	//Set handler functions
	GLUI_Master.set_glutDisplayFunc(drawScene);
	GLUI_Master.set_glutKeyboardFunc(handleKeypress);
	GLUI_Master.set_glutReshapeFunc(handleResize);
	GLUI_Master.set_glutMouseFunc(mouse);
	glutMotionFunc(motion);

	glui = GLUI_Master.create_glui_subwindow( main_window, GLUI_SUBWINDOW_BOTTOM );

	edittext = new GLUI_EditText( glui, "Cevabinizi kutucuga giriniz:", CevaplarText,2,control_cb);

	glui->set_main_gfx_window( main_window );
	GLUI_Master.set_glutIdleFunc( myGlutIdle );

	glutMainLoop();
}